package com.ctg.itrdc.sysmgr.portal.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.ctg.itrdc.pasp.context.service.BaseService;
import com.ctg.itrdc.sysmgr.portal.api.dto.FuncCompDTO;
import com.ctg.itrdc.sysmgr.portal.api.service.IFuncCompService;
import com.ctg.itrdc.sysmgr.portal.common.constant.DictEnum.StatusCd;
import com.ctg.itrdc.sysmgr.portal.common.constant.PrivGrantEnum;
import com.ctg.itrdc.sysmgr.portal.data.IFuncCompDao;
import com.ctg.itrdc.sysmgr.portal.data.IPrivFuncRelDao;
import com.ctg.itrdc.sysmgr.portal.data.IPrivilegeDao;
import com.ctg.itrdc.sysmgr.portal.data.ISystemRolesDao;
import com.ctg.itrdc.sysmgr.portal.data.entity.FuncComp;
import com.ctg.itrdc.sysmgr.portal.data.entity.PrivFuncRel;
import com.ctg.itrdc.sysmgr.portal.data.entity.Privilege;
import com.ctg.itrdc.sysmgr.portal.data.vo.FuncCompVO;
import com.ctg.itrdc.sysmgr.portal.service.utils.BeanUtils;
import com.google.common.collect.Lists;

@Component("funcCompService")
public class FuncCompServiceImpl extends BaseService<FuncComp, Long, FuncCompDTO> implements IFuncCompService, PrivGrantEnum{
    @Resource
    private IFuncCompDao funcCompDao;
    @Resource
    private ISystemRolesDao systemRolesDao;
    @Resource
	private IPrivFuncRelDao privFuncRelDao;
    @Resource
	private IPrivilegeDao privilegeDao;

    @Transactional
    @Override
    public Long insert(FuncCompDTO dto){
    	// 插入 func_comp
    	Long i = super.insert(dto);
    	dto.setCompId(i);
    	insertPriAndPriFuncRel(dto);
		return i;
    	
    }

    @Override
    public int updateByPrimaryKey(FuncCompDTO dto) {
    	// 更新 func_comp
    	Integer i = super.updateByPrimaryKey(dto);
    	// 更新 privilege
    	PrivFuncRel privFuncRel = new PrivFuncRel();
		privFuncRel.setPrivRefId(dto.getId());
		privFuncRel.setPrivRefType(PrivRefType.COMP.toString());
		List<PrivFuncRel> privFuncRelList = privFuncRelDao.selectByExample(privFuncRel);
		if(CollectionUtils.isNotEmpty(privFuncRelList)){
			for (PrivFuncRel pfr : privFuncRelList) {
				Long privId = pfr.getPrivId();
				// 更新 privilege
				Privilege privilege = new Privilege();
				privilege.setPrivId(privId);
				privilege.setPrivName(dto.getCompName());
//				DTOHelper.initDTO(dto, privilege); 
				privilegeDao.updateByPrimaryKey(privilege);
			}
		}else{
			// 没有的情况重新插入
			FuncCompDTO tmp = super.selectByPrimaryKey(dto);
			insertPriAndPriFuncRel(tmp);
		}
		return i;
    };
    
    @Transactional
    @Override
	public int deleteByPrimaryKey(FuncCompDTO dto) {
    	// 删除priv_func_rel和privilege的操作通过aop的方式进行。
    	// 由于privilege的删除均是在func_menu或者func_comp删除的情况下进行，
    	// 因此privilege的删除无需再增加事务
    	// 删除 func_comp
    	Integer i = super.deleteByPrimaryKey(dto);
		return i;
    }
    
    @Transactional
    @Override
    public int[] batchDeleteByPrimaryKey(List<FuncCompDTO> dtoList) {
		// 删除priv_func_rel和privilege的操作通过aop的方式来完成
    	// 由于privilege的删除均是在func_menu或者func_comp删除的情况下进行，
    	// 因此privilege的删除无需再增加事务
		// 删除 func_comp
		List<FuncComp> entities = BeanUtils.copyListNotException(dtoList, FuncComp.class);
		return funcCompDao.jdbcBatchDeleteByPrimary(entities);
    }
    
    @Override
    public List<FuncCompDTO> selectCompList(Long sysPostId, Long sysUserId){
		return this.selectCompList(sysPostId,sysUserId,new FuncCompDTO());
    }
    
    @Override
    public List<FuncCompDTO> selectCompList(Long sysPostId, Long sysUserId,FuncCompDTO funcCompDTO){
//    	Long menuId = null;
//    	if(funcCompDTO!=null && funcCompDTO.getMenuId()!=null){
//    		menuId = funcCompDTO.getMenuId().longValue();
//    	}
    	List<FuncCompDTO> dtoList = Lists.newArrayList();
		List<FuncCompDTO> sysUserComp = selectCompListBySysUserId(sysUserId,funcCompDTO);
		List<FuncCompDTO> sysPostComp = selectCompListBySysPostId(sysPostId,funcCompDTO);
		dtoList.addAll(sysUserComp);
		dtoList.addAll(sysPostComp);
    	return dtoList;
    }
    
    @Override
    public List<FuncCompDTO> selectCompList(String grantObjType,Long grantObjId,FuncCompDTO funcCompDTO){
    	
//    	Long menuId = null;
//    	if(funcCompDTO!=null && funcCompDTO.getMenuId()!=null){
//    		menuId = funcCompDTO.getMenuId().longValue();
//    	}
    	
    	List<FuncCompDTO> resultList = this.selectByIds(null,funcCompDTO);
    	
    	if(StringUtils.isNotBlank(grantObjType) && grantObjId !=null){
			GrantSysobjType type = GrantSysobjType.valueOf(grantObjType);
			List<FuncCompDTO> hadList = this.selectByIds(type,funcCompDTO,grantObjId);
			for (FuncCompDTO comp : resultList) {
				comp.setHadPriv(false);
				for (FuncCompDTO had : hadList) {
					if(comp.getCompId().equals( had.getCompId())){
						comp.setHadPriv(true);
						comp.setPrivGrantId(had.getPrivGrantId());
					}
				}
			}
		}
    	return resultList;
    }
    
    @Override
    public Boolean existComp(String grantObjType,Long grantObjId,FuncCompDTO dto){
    	FuncComp entity = BeanUtils.applyIfNotException(dto, FuncComp.class);
    	GrantSysobjType type = null;
    	if(StringUtils.isNotBlank(grantObjType))
    		type =  GrantSysobjType.valueOf(grantObjType);
    	
    	return funcCompDao.exist(type, entity, grantObjId);
    }
    
    @Override
    public List<FuncCompDTO> selectByIds(GrantSysobjType sysobjType, FuncCompDTO dto, Long... ids){
    	FuncComp entity = BeanUtils.applyIfNotException(dto, FuncComp.class);
    	List<FuncCompVO> voList = funcCompDao.selectByIds(sysobjType, entity, ids);
    	return BeanUtils.copyListNotException(voList, FuncCompDTO.class);
    }
    
	private List<FuncCompDTO> selectCompListBySysUserId(Long sysUserId,FuncCompDTO dto){
		FuncComp entity = BeanUtils.applyIfNotException(dto, FuncComp.class);
		List<FuncCompVO> entityList = Lists.newArrayList();
		Long[] roleIds = systemRolesDao.selectRoleIdsBySysUserId(sysUserId);
		List<FuncCompVO> sysRoleComps = funcCompDao.selectByIds(GrantSysobjType.SYSTEM_ROLE, entity,roleIds);
		List<FuncCompVO> sysUserComps = funcCompDao.selectByIds(GrantSysobjType.SYSTEM_USER, entity,sysUserId);
		entityList.addAll(sysRoleComps);
		entityList.addAll(sysUserComps);
		return BeanUtils.copyListNotException(entityList, FuncCompDTO.class);
	}
	
	private List<FuncCompDTO> selectCompListBySysPostId(Long sysPostId,FuncCompDTO dto){
		FuncComp entity = BeanUtils.applyIfNotException(dto, FuncComp.class);
		List<FuncCompVO> entityList = Lists.newArrayList();
		Long[] roleIds = systemRolesDao.selectRoleIdsBySysPostId(sysPostId);
		List<FuncCompVO> sysRoleComps = funcCompDao.selectByIds(GrantSysobjType.SYSTEM_ROLE,entity, roleIds);
		List<FuncCompVO> sysPostComps = funcCompDao.selectByIds(GrantSysobjType.SYSTEM_POST,entity, sysPostId);
		entityList.addAll(sysRoleComps);
		entityList.addAll(sysPostComps);
		return BeanUtils.copyListNotException(entityList, FuncCompDTO.class);
	}
	
	private void insertPriAndPriFuncRel(FuncCompDTO dto) {
		// 插入 privilege
    	Privilege privilege = new Privilege();
		privilege.setPrivName(dto.getCompName());
		privilege.setStatusCd(StatusCd.S0A.toString());
//		DTOHelper.initDTO(dto, privilege);
		long x = privilegeDao.insert(privilege);
    	// 插入 priv_func_rel
		PrivFuncRel privFuncRel = new PrivFuncRel();
		privFuncRel.setPrivId(x);
		privFuncRel.setPrivRefId(dto.getCompId());
		privFuncRel.setPrivRefType(PrivRefType.COMP.toString());
		privFuncRel.setStatusCd(StatusCd.S0A.toString());
//		DTOHelper.initDTO(dto, privFuncRel);
		privFuncRelDao.insert(privFuncRel);
	}
    
}
